home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-04 | 30.4 KB | 909 lines | [TEXT/PJMM] |
- {This document is formated in monaco 9 pt }
- { }
- {LEGAL STUFF }
- { }
- {Portions Copyright © 1994 by University of Melbourne. All Rights Reserved. }
- {This work is provided "as is" and without any express or implied warranties, }
- {including, without limitation, the implied warranties of merchantability and }
- {fitness for a particular purpose. }
- { }
- {University of Melbourne is not responsible for the consequences of the use of this}
- {work, regardless of the cause. You may use this work in a public domain, }
- {freeware, or shareware product with no restrictions, as long as you include }
- {the following notice in your product's about box or splash screen: }
- { "Portions Copyright © 1994 by University of Melbourne". }
- {If you use more than 50 lines of this work, please credit the author(s) also: }
- { "Portions by Sean J. Crist and Michael Cutter" }
- {Public domain is defined as something that you release to the public, without }
- {copyright and without restrictions on use. Freeware is a copyrighted work, }
- {for which you charge no money. Shareware is a copyrighted work for which you }
- {charge a fee if the user decides to keep it. If you intend to use this work }
- {in a commercial product, please contact us. }
- { }
- { }
- {OTHER STUFF }
- { }
- {Authors: }
- { Sean J. Crist }
- { Michael Trevor Cutter }
- { }
- {Contact: }
- { Internet: }
- { mtc@arbld.unimelb.edu.au (Preferred) }
- { kurisuto@bach.udel.edu }
- { }
- { Snail Mail: }
- { Dept of Architecture & Building }
- { University of Melbourne }
- { Parkville VIC 3052 }
- { AUSTRALIA }
- { }
- {PERSONAL STUFF: }
- { I'd really appreciate it if you'd let me know what you're using my code }
- { in, (send me email or a postcard). Please report any bugs or errors to me. }
- { }
- {MODULE DESCRIPTION: }
- {These procedures are built upon the work or Sean J. Crist. His comments are below }
- {I have modified most of his procedures, and added many of my own. I have labelled }
- {those which I wrote myself, and documented the changes I have made. I have also }
- {renamed them for my own convenience in order to distinguish them in my code. }
- {Sean, I hope you don't mind. I have included the original information he wrote }
- {below, however check out the interface listing for up to date data. }
- {The essential changes are adding facilities to access cells by index and allowing }
- {for multiple (or no) selections. }
-
- {From: kurisuto@BACH.UDEL.EDU ("Sean J. Crist") }
- {Subject: More free code: Simplifying the List Manager }
- {Date: 18 Sep 92 03:33:13 GMT }
- {}
- { The following code, once again, is nothing particularly glamorous; it }
- {simply makes it easier to use the List Manager to create and manage lists}
- {of strings. One of the most common uses for the List Manager is}
- {scrollable, one-dimensional, fixed-size}
- {lists of strings (as in SFGetFile, SFPutFile). The List Manager is good}
- {for creating all kinds of lists (such as lists of icons), but a lot of}
- {this functionality is a hassle for programmers who only need a simple list}
- {of strings.}
- { The code below allows you create and dispose of lists of strings. It}
- {allows you to add, rename, and remove elements in the list, and handles}
- {mouse clicks and update events. It also keeps the lists in alphabetical}
- {order.}
- { I remember having a lot of trouble learning how to call the List}
- {Manager properly; I hope that this code helps somebody else.}
- {}
- {How to use these routines:}
- { Every one of these routines takes a ListHandle as one of its}
- {parameters. It is OK to have several lists going at one time; just make}
- {sure you pass the right ListHandle when you call one of these routines.}
- { }
- {CreateList: Call this routine to create a new list of strings. Pass it}
- {an empty ListHandle, as well as the pointer to the window to contain the}
- {list, and the rectangle in which the list should be enclosed. The list}
- {can take up an entire window, or only}
- {part of it, as you prefer. The scroll bar will be drawn inside the}
- {rectangle you specify, so you don't need to leave extra room for it. }
- {Initially, the list will contain no strings.}
- {}
- {UpdateList: Call this in response to an Update event to redraw the}
- {portions of the list which need it. This routine assumes that you have}
- {already called BeginUpdate for the window containing the list, and that}
- {you have not yet called EndUpdate.}
- {}
- {DoClick: Call this function in response to a MouseDown event inside your}
- {list's rectangle. DoClick usually returns FALSE, but it returns TRUE if}
- {this click is the second click of a double-click (i.e., TRUE means the}
- {user double-clicked an item).}
- {}
- {TurnOffSelection: This routine unhilights the currently hilighted cell,}
- {if any.}
- {}
- {ListSelection: This returns the string of the currently selected cell. }
- {If no cell is currently selected, the empty string is returned.}
- {}
- {AddCell: Call this routine to add a new cell to the list. The string you}
- {pass to this routine is automatically alphabetized within the list. Bug}
- {alert: the first element or two of the list are sometimes not in}
- {alphabetical order. If you take the time}
- {to work out this kink, please let me know what you did (I could figure}
- {this out, but I just haven't taken the time to). This bug is cosmetic and}
- {does not crash the program.}
- {}
- {RenameCell: Changes the string in a cell to another string, and}
- {realphabetizes the list, if necessary. }
- {}
- {DeleteCell: Removes the cell with the given string from the list.}
- {}
- {DisposList: Call this routine when you are completely finished with a}
- {list and want to deallocate its memory.}
- {}
- { Credit: The routines CreateList, UpdateList, DoClick, and DisposList}
- {are loosely based on some code I received from somebody of}
- {comp.sys.mac.programmer around two years ago. I've rewritten these}
- {routines, but credit is due to this contributor, whose}
- {name I cannot remember.}
- {}
- { I have successfully called these routines for lists in regular}
- {windows as well as in modal dialogs. Please send bug reports, praise,}
- {money, etc. to kurisuto@bach.udel.edu.}
- {}
- unit MCSimpleLists;
-
- interface
- uses
- MCCursor; {only in the MCSortList function}
-
- const
- StandardListLDEF = 0;
- kMCSLScrollBarWidth = 16;
- {width of the scrollbar as created by MCCreateList}
-
- type
- {CellIndex is provided as a reminder that when passing in a value of}
- {this type, it refers to the cell index, which starts at 1, not 0.}
- CellIndex = integer;
- {Explanation: CellIndex calls assume that the cells are numbered 1..n.}
- {The Cell.v variable contains index - 1, i.e numbers the cells from 0..n-1}
- {I did this because I am a pascal diehard}
-
- {Author: Sean J. Crist}
- {Modified by Mike Cutter to include option for specifying LDEF and cell height.}
- {Create a new list with no elements.}
- {listh should be nil, thewindow <> nil, LDEFID can be StandardListLDEF if you}
- {just want a standard list, or the resid of the LDEF if you don't, cellHeight}
- {is calculated from the text height if you set it to 0, and obviously theRect}
- {is where to put it in local coordinates}
- procedure MCCreateList (var listh: ListHandle;
- TheWindow: WindowPtr;
- LDEFID: integer;
- cellHeight: integer;
- TheRect: Rect);
-
- {Author: Sean J. Crist}
- {Modified by Mike Cutter to detect nil list}
- {Update the art of a list. Call this in your update routine, or put it into}
- {a drawing routine for your useritem in a dialog (you can store the list into}
- {the refcon of the dialog)}
- procedure MCUpdateList (listh: ListHandle);
-
- {Author: Sean J. Crist}
- {Modified by Mike Cutter to detect clicks in non-existant cells}
- {Handle a click in the list rectangle. If it was a double-click, we will}
- {return TRUE. Pass 0 in modifiers if you just want a single selection list,}
- {event.modifiers if you want multiple selection etc.}
- {if you want to be sure you clicked in an actual existing cell (and not in an}
- {empty space, check goodClick. Pass in goodClick = true to get it to check, if you}
- {don't care, goodClick = false}
- function MCDoClickList (listh: ListHandle;
- TheWhere: Point;
- Modifiers: integer;
- var goodClick: Boolean): Boolean;
-
- {Author: Michael Cutter}
- {Get the index of the last cell clicked in. Don't forget, this won't have much bearing}
- {if the user has dragged across several cells. But if they double-clicked, that will tell}
- {us which cell it was that they doubleclicked}
- function MCGetLastIndexedClicked (listh: ListHandle): CellIndex;
-
- {Author: Michael Cutter}
- {Enable and disable drawing of the list}
- procedure MCNoListDraw (listh: ListHandle);
- procedure MCYesListDraw (listh: ListHandle);
-
- {Author: Sean J. Crist}
- {Modified by Mike Cutter to turn off multiple selections, rather than just the first}
- {Turn off any hilited item.}
- procedure MCTurnOffListSelection (listh: ListHandle);
-
- {Author: Mike Cutter}
- {Get the visible rectangle of the list in local coordinates}
- procedure MCGetListViewRect (list: ListHandle;
- var lrect: Rect);
-
- {Author: Mike Cutter}
- {Check whether a specified item is in the list}
- function MCCheckForCell (listh: ListHandle;
- TheStr: string): Boolean;
-
- {Author: Mike Cutter}
- {Select the first item in the list, useful when a list has just been created}
- procedure MCSelectFirstCell (listh: ListHandle;
- oneselection: Boolean);
-
- {Author: Mike Cutter}
- {Select an item specified by its contents. Set oneselection = true if you only}
- {ever want one item to be selected, otherwise set it to false if you want multiple}
- {selections permitted.}
- procedure MCSelectCell (listh: ListHandle;
- TheStr: string;
- oneselection: Boolean);
-
- {Author: Sean J. Crist}
- {Modified by Mike Cutter to detect nil listh}
- {Returns the single string currently selected; empty string if no selection . }
- function MCGetListSelection (listh: ListHandle): string;
-
- {Author: Mike Cutter}
- {Used to retrieve all the selected cells, one after the other.}
- {Set last to 0 first, increment it after calling the function to avoid}
- {finding same cell again. Returns -1 in last when at the end of the selected cells}
- function MCGetNextListSelection (listh: ListHandle;
- var last: CellIndex): Str255;
-
- {Author: Mike Cutter}
- {Returns the number of selected items in the list}
- function MCCountListSelected (listh: ListHandle): integer;
-
- {Author: Sean J Crist}
- {Modified by Mike Cutter to leave sorting the list till after it has been created.}
- {Add a new cell to the end of the list}
- procedure MCAddCell (listh: ListHandle;
- NewStr: str255);
-
- {Author: Mike Cutter}
- {Count the number of cells}
- function MCCountListCells (listh: ListHandle): integer;
-
- {Author: Mike Cutter}
- {Select the cell specified by the index}
- procedure MCSelectIndexedCell (listh: ListHandle;
- index: CellIndex;
- oneselection: Boolean);
-
- {Author: Mike Cutter}
- {Get the contents of the index'th cell}
- function MCGetIndexedListCell (listh: ListHandle;
- index: CellIndex): Str255;
-
- {Author: Mike Cutter}
- {Get the index of the named cell}
- function MCGetCellIndex (listh: ListHandle;
- TheStr: Str255): CellIndex;
-
- {Author: Mike Cutter}
- {Set the name of the index'th cell}
- procedure MCSetIndexedListCell (listh: ListHandle;
- index: CellIndex;
- NewStr: string);
-
- {Author: Mike Cutter}
- {Sort the list alphabetically}
- procedure MCSortList (listh: ListHandle);
- {note this doesn't require an index, but it uses indexed functions}
-
- {Author: Sean J. Crist}
- {Modified by Mike Cutter to detect nil list}
- {Change the name of an existing cell}
- procedure MCRenameCell (listh: ListHandle;
- OldStr, NewStr: Str255);
-
- {Author: Sean J. Crist}
- {Modified by Mike Cutter to detect a nil list}
- {Remove the cell with the given name from the list.}
- procedure MCDeleteCell (listh: ListHandle;
- TheStr: string);
-
- {Author: Mike Cutter}
- {Remove the indexed cell from the list}
- procedure MCDeleteIndexedCell (listh: ListHandle;
- index: CellIndex);
-
- {Author Sean J. Crist}
- {Modified by Mike Cutter to detect a nil list}
- {Get rid of the list when we're done with it, cleaning up all the memory.}
- procedure MCDisposeList (listh: ListHandle);
-
- implementation
- var
- gMCSLCellHeight: integer; {for remembering the cellheight for MCDoClick}
-
- procedure MCCreateList (var listh: ListHandle;
- TheWindow: WindowPtr;
- LDEFID: integer;
- cellHeight: integer;
- TheRect: Rect);
- var
- ViewRect: Rect;
- DataBounds: Rect;
- CellSize: Point;
- TempInteger: Integer; {Just to do a little math}
- begin
- if listh <> nil then
- begin
- DebugStr('list handle not initialized to nil in MCCreateList');
- end;
- {Inset the box to make room for the scroll bar. Also inset it so we've got room for a border.}
- ViewRect := TheRect;
- InsetRect(ViewRect, 1, 1);
- ViewRect.Right := ViewRect.Right - 15;
- {Set the cell size to the size of the cell}
- if cellHeight = 0 then
- {we don't care what the cellheight is, so work it out from the window text font}
- begin
- CellSize.v := TheWindow^.txSize + 3;
- if CellSize.v = 3 then {If it hasn't been set, then make it 12 point.}
- begin
- TextSize(12);
- CellSize.v := 15;
- end;
- end
- else
- CellSize.v := cellHeight;
- gMCSLCellHeight := CellSize.v;
- {set the width}
- CellSize.h := ViewRect.Right - ViewRect.Left;
-
- {Now adjust the ViewRect to avoid cutting off the last visible cell}
- TempInteger := (ViewRect.Bottom - ViewRect.Top) div CellSize.v;
- ViewRect.Bottom := ViewRect.Top + (TempInteger * CellSize.v);
-
- { and create the new list.}
- SetRect(DataBounds, 0, 0, 1, 0);
- listh := LNew(ViewRect, DataBounds, CellSize, LDEFID, TheWindow, FALSE, FALSE, FALSE, TRUE);
- MCUpdateList(listh);
- end;
-
- {Update the display of a list.}
- procedure MCUpdateList;
- var
- ViewRect: Rect;
- ListUpdateRgn: RgnHandle;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCUpdateList');
- exit(MCUpdateList);
- end;
- SetPort(listh^^.Port);
- {Get the List manager to update the list.}
- ViewRect := listh^^.rView;
- EraseRect(ViewRect); {erase the rect}
- LDoDraw(true, listh);
- ListUpdateRgn := NewRgn;
- RectRgn(ListUpdateRgn, ViewRect);
- LUpdate(ListUpdateRgn, listh);
- {Draw the border}
- InsetRect(ViewRect, -1, -1);
- FrameRect(ViewRect);
- {Clean up after ourselves}
- DisposeRgn(ListUpdateRgn);
- end;
-
- {Handle a click in the list rectangle. If it was a double-click, we will return TRUE.}
- {trick to avoiding bad clicks, is to check that the click is in the rect defined}
- {by the number of items in the list, _IF_ the list count * the cellheight is smaller}
- {than the rect of the list.}
- {Note that we aren't passing in the modifiers with the click, thus forcing this list}
- {to only ever behave as a single selection list}
- {To allow multiple selections, there needs to be a way of getting each selection in order}
- {and clicks must be sent to a different (but similar) function which receives and passes}
- {on the event.modifiers}
- function MCDoClickList;
- var
- cellsRect, viewRect: Rect;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCDoClickList');
- exit(MCDoClickList);
- end;
- SetPort(listh^^.Port);
- cellsRect := listh^^.rView;
- {adjust to include the scroll bar}
- cellsRect.right := cellsRect.right + kMCSLScrollBarWidth;
- viewRect := cellsRect; {remember the visible rectangle}
- {and adjust the cellsrect to be the size of all the existing cells - which}
- {may or may not be bigger than the visible rect}
- cellsRect.bottom := cellsRect.top + (listh^^.cellSize.v * MCCountListCells(listh)); {}
- if goodClick then
- if PtInRect(TheWhere, viewRect) then {got a click in either the scrollbar or the list}
- if PtInRect(theWhere, cellsRect) then {got a click inside the cells}
- begin
- LDoDraw(TRUE, listh);
- MCDoClickList := LClick(TheWhere, modifiers, listh);
- goodClick := true;
- end
- else
- begin
- viewRect.left := viewRect.right - kMCSLScrollBarWidth;
- if not PtInRect(theWhere, viewRect) then {check it wasn't a click in the sb}
- begin
- SysBeep(1);
- end;
- goodClick := false; {wasn't a click on a list item}
- end
- else {did't click in the list, idiot!}
- else
- begin
- LDoDraw(true, listh);
- MCDoClickList := LClick(TheWhere, modifiers, listh);
- end;
- end;
-
- function MCGetLastIndexedClicked (listh: ListHandle): CellIndex;
- var
- cellpt: Cell;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCGetLastIndexedClicked');
- MCGetLastIndexedClicked := 0;
- exit(MCGetLastIndexedClicked);
- end;
- SetPt(cellpt, 0, 0);
- cellpt := LLastClick(listh);
- MCGetLastIndexedClicked := cellpt.v + 1; {because indexes go from 1..cellcount}
- end;
-
- procedure MCNoListDraw (listh: ListHandle);
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCNoListDraw');
- exit(MCNoListDraw);
- end;
- LDoDraw(false, listh);
- end;
-
- procedure MCYesListDraw (listh: ListHandle);
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCYesListDraw');
- exit(MCYesListDraw);
- end;
- LDoDraw(true, listh);
- end;
-
- {Turn off all hilited items.}
- procedure MCTurnOffListSelection;
- var
- ResultPoint: Cell;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCTurnOffListSelection');
- exit(MCTurnOffListSelection);
- end;
- SetPt(ResultPoint, 0, 0);
- while LGetSelect(TRUE, ResultPoint, listh) do
- begin
- LSetSelect(FALSE, ResultPoint, listh);
- SetPt(ResultPoint, 0, 0);
- end;
- end;
-
- {Get the visible rectangle of the list}
- procedure MCGetListViewRect (list: ListHandle;
- var lrect: Rect);
- begin
- if list = nil then
- begin
- DebugStr('list handle is nil in MCGetListViewRect');
- exit(MCGetListViewRect);
- end;
- lrect := list^^.rView;
- end;
-
- {Check the existence of a particular cell}
- function MCCheckForCell;
- var
- CellPoint: Cell;
- DataPtr: Ptr;
- DataLen: Integer;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCCheckForCell');
- MCCheckForCell := false;
- exit(MCCheckForCell);
- end;
- SetPt(CellPoint, 0, 0);
- DataPtr := Pointer(Ord(@TheStr) + 1);
- dataLen := Length(TheStr);
- MCCheckForCell := LSearch(dataPtr, dataLen, nil, CellPoint, listh);
- end;
-
- {Select the first item}
- procedure MCSelectFirstCell;
- {By Michael Cutter, Sept 93}
- var
- CellPoint: Cell;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCSelectFirstCell');
- exit(MCSelectFirstCell);
- end;
- if MCCountListCells(listh) > 0 then
- begin
- if oneselection then
- begin
- SetPt(CellPoint, 0, 0);
- while LGetSelect(TRUE, CellPoint, listh) do
- begin
- LSetSelect(FALSE, CellPoint, listh);
- SetPt(CellPoint, 0, 0);
- end;
- end;
- SetPt(CellPoint, 0, 0);
- LSetSelect(TRUE, CellPoint, listh);
- end;
- end;
-
- {Select a particular item}
- procedure MCSelectCell;
- {By Michael Cutter, Sept 93}
- var
- OldPoint, CellPoint: Cell;
- DataPtr: Ptr;
- DataLen: Integer;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCSelectCell');
- exit(MCSelectCell);
- end;
- if MCCountListCells(listh) > 0 then
- begin
- SetPt(CellPoint, 0, 0);
- DataPtr := Pointer(Ord(@TheStr) + 1);
- dataLen := Length(TheStr);
- if LSearch(dataPtr, dataLen, nil, CellPoint, listh) then
- begin
- if oneselection then
- begin {deselect any current selection}
- SetPt(OldPoint, 0, 0);
- while LGetSelect(TRUE, OldPoint, listh) do
- begin
- LSetSelect(FALSE, OldPoint, listh);
- SetPt(OldPoint, 0, 0);
- end;
- end;
- {select the cell we want}
- LSetSelect(TRUE, CellPoint, listh);
- end
- else
- begin
- {The programmer asked us to select a cell which doesn't exist. We'll just beep angrily }
- {three times. It's the programmer's responsibility to see that the cell in question actually}
- {does exist before calling this routine.}
- Sysbeep(1);
- Sysbeep(1);
- Sysbeep(1);
- end;
- end;
- end;
-
- {Return the string currently selected; empty string if no selection.}
- function MCGetListSelection;
- var
- ResultPoint: Cell;
- ResultString: Str255;
- StringPointer: Ptr;
- StringLength: Integer;
- begin
- MCGetListSelection := '';
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCGetListSelection');
- exit(MCGetListSelection);
- end;
- SetPt(ResultPoint, 0, 0);
- if LGetSelect(TRUE, ResultPoint, listh) then
- {If there is a cell selected, then get the string value of that string. }
- {There ought to be an easier way to do this than mucking around in the }
- {memory like this. >:-( }
- begin {If there is a cell selected, then return the string of the cell.}
- StringPointer := Ptr(Ord(@ResultString) + 1);
- StringLength := 255; {This is the maximum amount of data we are allowed to move.}
- LGetCell(StringPointer, StringLength, ResultPoint, listh);
- StringPointer := Ptr(Ord(@ResultString));
- StringPointer^ := StringLength;
- MCGetListSelection := ResultString;
- end; {Otherwise, return the empty string to show that nothing is selected.}
- end;
-
- function MCGetNextListSelection (listh: ListHandle;
- var last: CellIndex): Str255;
- var
- ResultPoint: Cell;
- stringsize: integer;
- str: Str255;
- begin
- str := '';
- ResultPoint.h := 0;
- ResultPoint.v := last;
- if LGetSelect(TRUE, ResultPoint, listh) then
- begin
- stringsize := sizeof(Str255);
- LGetCell(@str, stringsize, ResultPoint, listh);
- last := ResultPoint.v
- end
- else
- last := -1; {no more selected items}
- MCGetNextListSelection := str;
- end;
-
- function MCCountListSelected (listh: ListHandle): integer;
- var
- CellPoint: Cell;
- count: integer;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCCountListSelected');
- MCCountListSelected := 0;
- exit(MCCountListSelected);
- end;
- count := 0;
- SetPt(CellPoint, 0, 0);
- while LGetSelect(TRUE, CellPoint, listh) do
- begin
- count := count + 1;
- CellPoint.v := CellPoint.v + 1;
- end;
- MCCountListSelected := count;
- end;
-
- procedure MCAddCell;
- var
- CellPoint: Cell;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCAddCell');
- exit(MCAddCell);
- end;
- {Add the new row at the top of the list.}
- SetPt(CellPoint, 0, 0);
- CellPoint.v := LAddRow(1, CellPoint.v, listh);
- {Put the string into the cell. Once again, there ought to be an easier}
- {way to do this.}
- LSetCell(Pointer(Ord(@NewStr) + 1), Length(NewStr), CellPoint, listh);
- end;
-
- procedure MCSelectIndexedCell (listh: ListHandle;
- index: CellIndex;
- oneselection: Boolean);
- var
- OldPoint, CellPoint: Cell;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCSelectIndexedCell');
- exit(MCSelectIndexedCell);
- end;
- CellPoint.h := 0;
- CellPoint.v := index - 1;
- if oneselection then
- begin
- {deselect any current selection}
- SetPt(OldPoint, 0, 0);
- while LGetSelect(TRUE, OldPoint, listh) do
- begin
- LSetSelect(FALSE, OldPoint, listh);
- SetPt(OldPoint, 0, 0);
- end;
- end;{select the cell we want}
- LSetSelect(TRUE, CellPoint, listh);
- end;
-
- function MCGetIndexedListCell;
- {By Michael Cutter, Sept 1993}
- var
- CellPoint: Cell;
- StringPointer: Ptr;
- StringLength: Integer;
- NewStr: Str255;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCGetIndexedListCell');
- MCGetIndexedListCell := '';
- exit(MCGetIndexedListCell);
- end;
- NewStr := '';
- if (index <= MCCountListCells(listh)) and (index > 0) then
- begin
- SetPt(CellPoint, 0, index - 1);
- StringPointer := Ptr(Ord(@NewStr) + 1);
- StringLength := 255;
- LGetCell(StringPointer, StringLength, CellPoint, listh);
- StringPointer := Ptr(Ord(@NewStr));
- StringPointer^ := StringLength; {assign the length byte}
- end;
- MCGetIndexedListCell := NewStr;
- end;
-
- function MCCountListCells;
- {By Michael Cutter, Sept 1993, revised Mar 1994}
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCCountListCells');
- MCCountListCells := 0;
- exit(MCCountListCells);
- end;
- with listh^^.dataBounds do
- MCCountListCells := bottom * right; {if there is only one column, then right = 1}
- end;
-
- function MCGetCellIndex (listh: ListHandle;
- TheStr: Str255): CellIndex;
- {By Michael Cutter, March 94}
- var
- OldPoint, CellPoint: Cell;
- DataPtr: Ptr;
- DataLen: Integer;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCGetCellIndex');
- MCGetCellIndex := 0;
- exit(MCGetCellIndex);
- end;
- SetPt(CellPoint, 0, 0);
- DataPtr := Pointer(Ord(@TheStr) + 1);
- dataLen := Length(TheStr);
- if LSearch(dataPtr, dataLen, nil, CellPoint, listh) then
- begin
- {return the index of the cell we wanted}
- MCGetCellIndex := CellPoint.v + 1;
- end
- else
- MCGetCellIndex := 0;
- end;
-
- procedure MCSetIndexedListCell (listh: ListHandle;
- index: CellIndex;
- NewStr: string);
- var
- CellPoint: Cell;
- StringPointer: Ptr;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCSetIndexedListCell');
- exit(MCSetIndexedListCell);
- end;
- if (index <= MCCountListCells(listh)) and (index > 0) then
- begin
- SetPt(CellPoint, 0, index - 1);
- StringPointer := Ptr(Ord(@NewStr) + 1);
- LSetCell(StringPointer, length(NewStr), CellPoint, listh);
- end;
- end;
-
- procedure MCSortList (listh: ListHandle);
- {By Michael Cutter, Sept 1993}
- var
- itemcount, index, ind2: CellIndex;
- curritem, previtem: str255;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCSortList');
- exit(MCSortList);
- end;
- MCNoListDraw(listh);
- itemcount := MCCountListCells(listh);
- for index := 2 to itemcount do
- begin
- MCNextAnimCursor;
- curritem := MCGetIndexedListCell(listh, index); {get the string of the index'th menu item}
- ind2 := index;
- previtem := MCGetIndexedListCell(listh, ind2 - 1); {get the string of the index-1'th menu item}
- while (RelString(curritem, previtem, false, false) < 0) and (ind2 <> 1) do {while curritem less than previtem}
- begin
- MCNextAnimCursor;
- MCSetIndexedListCell(listh, ind2, MCGetIndexedListCell(listh, ind2 - 1));
- ind2 := ind2 - 1;
- previtem := MCGetIndexedListCell(listh, ind2 - 1); {get the string of the index-1'th menu item}
- end;
- MCSetIndexedListCell(listh, ind2, curritem);
- end;
- MCYesListDraw(listh);
- end;
-
- procedure MCRenameCell;
- var
- CellPoint: Cell;
- DataPtr: Ptr;
- DataLen: Integer;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCRenameCell');
- exit(MCRenameCell);
- end;
- SetPt(CellPoint, 0, 0);
- DataPtr := Pointer(Ord(@OldStr) + 1);
- dataLen := Length(OldStr);
- if LSearch(dataPtr, dataLen, nil, CellPoint, listh) then
- begin
- DataPtr := Pointer(Ord(@NewStr) + 1);
- dataLen := Length(NewStr);
- LSetCell(DataPtr, dataLen, CellPoint, listh);
- end
- else
- begin
- {The programmer asked us to rename a cell which doesn't exist. We'll just}
- {beep angrily}
- {three times. It's the programmer's responsibility to see that the cell}
- {in question actually}
- {does exist before calling this routine.}
- Sysbeep(1);
- Sysbeep(1);
- Sysbeep(1);
- end;
- end;
-
-
- {Remove the cell with the given name from the list.}
- procedure MCDeleteCell;
- var
- CellPoint: Cell;
- DataPtr: Ptr;
- DataLen: Integer;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCDeleteCell');
- exit(MCDeleteCell);
- end;
- SetPt(CellPoint, 0, 0);
- DataPtr := Pointer(Ord(@TheStr) + 1);
- dataLen := Length(TheStr);
- if LSearch(dataPtr, dataLen, nil, CellPoint, listh) then
- begin
- LDelRow(1, CellPoint.v, listh);
- end
- else
- begin
- {The programmer asked us to delete a cell which doesn't exist. We'll just}
- {beep angrily}
- {three times. It's the programmer's responsibility to see that the cell}
- {in question actually}
- {does exist before calling this routine.}
- Sysbeep(1);
- Sysbeep(1);
- Sysbeep(1);
- end;
- end;
-
- {Remove the indexed cell from the list.}
- procedure MCDeleteIndexedCell;
- {By Mike Cutter, April 94}
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCDeleteIndexedCell');
- exit(MCDeleteIndexedCell);
- end;
- if index <= MCCountListCells(listh) then
- begin
- LDelRow(1, index - 1, listh);
- end
- else
- begin
- {The programmer asked us to delete a cell which doesn't exist. We'll just beep angrily}
- {three times. It's the programmer's responsibility to see that the cell}
- {in question actually does exist before calling this routine.}
- Sysbeep(1);
- Sysbeep(1);
- Sysbeep(1);
- end;
- end;
-
- {Get rid of the list when we're done with it, cleaning up all the memory.}
- procedure MCDisposeList;
- begin
- if listh = nil then
- begin
- DebugStr('list handle is nil in MCDisposeList');
- exit(MCDisposeList);
- end;
- LDispose(listh);
- end;
-
- end.